Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
AhmadAlsaadi
GitHub Repository: AhmadAlsaadi/Arabic-python-notebook
Path: blob/master/الفصل الخامس-حلقات التكرار.ipynb
671 views
Kernel: Python 3 (ipykernel)
import style style._set_css_style("custom.css")

الفصل الخامس : حلقات التكرار


ان من اكثر بواعث الملل ان يضطر الانسان الى اداء الاعمال ذاتها مرارا وتكرارا. وذلك لانه يرى في هذه الاعمال هدرا لوقته وجهده. فنجده قد بدأ بتحرير نفسه من قيود هذه الاعمال باسنادها الى الات من صنعة. ومن اشهر الالات التى اعتمد عليها لاداء هذا الغرض جهاز الكمبيوتر. ونجد ان حلقات التكرار المسوؤلة عن اعداد المهام المتكررة قد اصبحت جزء رئيسي وجوهري من اجزاء معظم لغات البرمجة المشهور. وفي لغة بايثون يتم عمل المهام المتكررة بواسطة تركيبين لغويين اساسين هما حلقة for وحلقة while واللتان تعتبران المحواران الرئيسيان لهذه الفصل.

أهداف الفصل

عند اتمام هذا الفصل يجب ان يكون لديك المام بالآتي:
  1. التعرف على كيفية استخدام حلقة التكرار for.
  2. التعرف على كيفية استخدام حلقة التكرار while.
  3. التعرف على مواضع التشابه والاختلاف بين مهام كل حلقة.

حلقة التكرار for

تستخدم حلقة for التكرارية عندما يراد اداء مهمة ما عدداً معلوماً من المرات. وافضل طريقة لتفصيل التركيب اللغوي لهذه الحلقة هي اعطاء امثله توضح طريقة عملها فالمثال التالي يقوم بطباعة أحرف كلمة بايثون واحداً تلو الآخر:
for x in "python": # عدد مرات التكرار تم تحديده هنا بعدد احرف كلمة بايثون print(x) # المهمة التي يراد تكرارها تكتب هنا # لاحظ الفراغ الذي ترك في بداية السطر
p y t h o n
من المثال السابق يمكن ملاحظة الآتي :
  1. تبدأ الحلقة بكلمة for.
  2. ينتهي السطر الاول من الحلقة بنقطتين فوق بعض ":". ويعتبر نسيان كتابة النقطتين من اشهر الاخطاء التي يقع فيها المبرمجين المبتدئين في لغة بايثون. لذلك احرص على تذكر كتابتها دائماً.
  3. لإعلام بايثون بالمهمة التي يراد تكرارها يترك فراغ في بداية السطر بمقدار حرف واحد على الاقل (Indentation). ومن المتعارف عليه في لغة بايثون ان يترك فراغ بمقدار 4 أحرف.
  4. يمكن كتابة المعنى الحرفي للتركيب اللغوي السابق كالاتي: "لكل حرف يرمز اليه بالمتغير x موجود في البيان النصي "python" قم بطباعة قيمة x على الشاشة.
  5. اسم المتغير هنا اختياري فيمكننا ان نستبدله باي متغير نحب فيمكننا مثلا ان نسميه letter فنحصل على نفس النتيجة كما في المثال التالي:
for letter in "python": # عدد مرات التكرار يحدد هنا print(letter) # المهمة التي يراد تكرارها تكتب هنا # لاحظ الفراغ الذي ترك في بداية السطر
p y t h o n
إذا أردنا أن نكرر أكثر من مهمة فإنه يجب مراعاة أن يكون عدد الفراغات المتروكة في بداية سطر كل مهمة متساوياً كما في المثال التالي:
for i in "car": print(i) print(i)
عند اختلاف عدد المسافات المتروكة في بداية سطر كل مهمة فان بايثون يعطي ملاحظة على وجود خطأ كما في المثال التالي:
for letter in "car": print(i) print(i)
في المثال السابق استخدمنا عدد الأحرف الموجودة في بيان نصي لتحديد عدد مرات التكرار. وهذه الطريقة ليست الوحيدة لتحديد عدد مرات التكرار فهناك البيانات التجميعية التي ذكرناها في الفصل الثالث يمكن ان نستخدمها ايضاً لتحديد عدد مرات التكرار. فالبيانات الموجودة في قائمة يمكن أن تستخدم لتحديد عدد مرات التكرار كما في المثال التالي:
students=['Ali','Ahmad','Hind','Omar'] for name in students: print(name)
Ali Ahmad Hind Omar
لاحظ أننا استخدمنا اسم المتغير هنا ليكون name وكان بإمكاننا أن نستخدم أي اسم آخر فالعملية هنا اختيارية بحته.
وكذلك الصفوف يمكن أن تستخدام لإجراء عمليات التكرار المحدد كما في المثال التالي:
for number in (1,2,3): #استخدام الصفوف لإجراء عملية التكرار على عناصرها print(number)
1 2 3
تعلمنا في الفصل الثالث أيضاً أن الدالتان ()keys و ()value عند استخدامها مع القواميس تعطي قائمة بالمفاتيح والقيم لذلك يمكن اجراء علميات التكرار عليها كما يلي:
d={1:"a",2:"b",3:"c"} print(d.values()) print(d.keys())
for value in d.values(): print(value)
for key in d.keys(): print(key)
كما يمكن استخدام الدالة ()range لتحديد عدد مرات التكرار وذلك لأنها تقوم بإنشاء قائمة من أعداد صحيحة كما في المثال التالي:
for number in range(5): print(number)
فالدالة ()range في الأصل تأخد ثلاث قيم من الأعداد الصحيحة اثنان منها إختياريان يمكن حذفهما كما في المثال السابق و الثالث متطلب أساسي لأنه يحدد الرقم الذي يجب أن تقف عنده قيم القائمة. فالعددان الإختياريان هما العددان الذان يحددان بداية القيمة التى تبدأ عندها القائمة والآخر يحدد عدد الخطوات التى تكون بين قيم القائمة.


فعند حذف القيم الإختيارية يفترض بايثون أنك تريد قائمة من أعداد صحيحة تبدأ من الصفر وتزيد بمقدار العدد 1. فالمثال السابق قام بايثون بإنتاج قائمة من أعداد الصحيحة بدأت من الصفر وتزايدت بمقدار 1 وتوقفت قبل الرقم 5. لاحظ أن العدد الذي يحدد توقف القائمة لايكون مشمولاً في القائمة. ويمكن استخدام الدالة ()range بثلاث قيم كما في المثال التالي:
for number in range(4,10,2): print(number)
فالقائمة السابقة بدأت بالعدد 4 و انتهت قبل العدد 10 وكان عدد الخطوات بمقدار 2.
كما يمكن أن يكون عدد الخطوات ذو قيمة سالبة لذلك يجب أن تكون قيمة البداية أكبر من النهاية كما في المثال التالي:
for number in range(16,6,-3): print(number)
عند استخدام قيمتين في الدالة ()range فان بايثون يفترض ان القيمة التي حذفت هي قيمة عدد الخطوات كما في المثال التالي:
for x in range(2,5): print(x)
2 3 4

تمارين استكشافية

١- اكتب برانامج يقوم بطباعة الأرقام من 0 الي 10 ؟
٢- اكتب برنامج يقوم بطباعة الاعداد الزوجية من 50 الى 100 ؟
٣- اكتب برنامج يقوم بجمع الأعداد من 1 إلى 100 ؟
٤- اكتب برنامج يقوم بطباعة كلمة “Hello” معكوسة؟
٥- اكتب برنامج يقوم بطباعة الأعداد الزوجية تنازلياً من 20 الي 0 ؟

كما يمكن عمل حلقة تكرار داخل حلقة تكرار بحيث يقوم البرنامج بتكرار حلقة التكرار الداخلية عددا من المرات مساويا لعناصر حلقة التكرار الخارجية كما في المثال التالي:

for a in range(1,4): for b in range(1,4): print(a,"*",b,"=",a*b)
1 * 1 = 1 1 * 2 = 2 1 * 3 = 3 2 * 1 = 2 2 * 2 = 4 2 * 3 = 6 3 * 1 = 3 3 * 2 = 6 3 * 3 = 9

في المثال السابق يأخذ المتغير a لحلقة التكرار الخارجية القيمة 1 من الدالة range ومن ثم يقوم بالدخول في حلقة التكرار الداخلية الممثلة بالمتغير b حيث تتكرر اربع مرات ثم يعود البرنامج الى حلقة التكرار الخارجية ليغير قيمة a الى القيمة 2 ثم يدخل مرة اخرى في حلقة التكرار الداخلية حتى تنتهي الحلقة الداخلية ويعود مره اخرى للحلقة الخارجية وهكذا يكمل البرنامج تنفيذ الكود البرمحي حتى تنتهي عناصر القيم الموجودة في الدالة range للحلقة الخارجية.

ايقاف حلقة التكرار قبل اكتمالها

ان توقف حلقة التكرار الافتراضي هو الانتهاء من كافة العناصر الموجودة في قائمة او عدد الحروف الموجودة في نص. لكن في بعض الاحيان يجد المبرمج ان اكمال حلقة التكرار لا فائدة منه (سوف نأخذ امثلة لاحقا على متى يكون اكمال حلقة التكرار لا فائدة منه ) فيعمد الي ايقاف حلقة التكرار باستخدام عبارة التوقف break. ولتعرف على كيفية استخدام عبارة التوقف break سوف نفرض اننا نود ان نكتب برنامجا يقوم بطباعة كل الفواكة الموجودة في قائمة ويتوقف البرنامج عن طباعة أسماء الفواكة ويخرج من حلقة التكرار بمجرد الوصول الى فاكهة الموز كما في المثال التالي:

fruits = ["apple", "orange","banana", "cherry"] for x in fruits: if x == "banana": break print(x)
apple orange

في المثال السابق كان لدينا قائمة باربعة فواكهة قمنا بعمل حلقة تكرار بعدد عناصرها وكان الكود البرمجي المطلوب تكراره هو التأكد من أن اسم الفاكهة المراد طباعتها ليس الموز لأنه بمجرد تحقق هذا الشرط يقوم البرنامج بتنفيذ العبارة break والتي تقوم باجبار البرنامج بالخروج من حلقة التكرار.

إن من المناسب ان نذكر هنا ان حلقات التكرار يمكن ان تستخدم العبارة else في تركيبها اللغوي وذلك للقيام بمهام عند الانتهاء من حلقة التكرار شريطة أن حلقة التكرار لم يتم إنهائها بواسطة العبارة break. كم في المثال التالي:

for i in range(1,4): print(i**2) else: print("loop is completed successfully")
1 4 9 loop is completed successfully

أما اذا تم إنهاء حلقة التكرار من خلال العبارة break فإن الأسطر البرمجية التي تقع داخل العبارة else لا يتم تنفيذها كما في المثال التالي:

fruits = ["apple", "orange","banana", "cherry"] for x in fruits: if x == "banana": break print(x) else: print("loop is completed successfully")
apple orange

لنضرب الآن مثالا آخر يوضح الحاجة الى استخدام break وعدم الرغبة في اكمال حلقة التكرار. لنفرض اننا نريد كتابة برنامج يقوم بتحديد الأعداد الأولية للأرقام من 2 الى 10. الأعداد الأولية هي الأرقام التي تقبل القسمة على نفسها وعلى العدد واحد فقط. للقيام بهذه المهمة نحتاج الى كتابة الكود التالي:

for n in range(2, 10): for x in range(2, n): if n % x == 0: print(n, 'equals', x, '*', n//x) break else: print(n, 'is a prime number')
2 is a prime number 3 is a prime number 4 equals 2 * 2 5 is a prime number 6 equals 2 * 3 7 is a prime number 8 equals 2 * 4 9 equals 3 * 3

البرنامج السابق يستخدم حلقتي تكرار واحدة داخلية والاخرى خارجية. الحلقة الخارجية تبدأ باستخدام القيمة 2 للمتغير n من الدالة range ومن ثم تدخل في حلقة تكرار داخلية لتقوم بتحديد نوع العدد الموجود في المتغير n والذي هنا اصبح يحمل القيمة 2 للتأكد ما اذا كان العدد 2 عدد أولي او لا. طريقة التحديد تعتمد على تكوين حلقة تكرار من خلال الدالة range التي تبتدأ بالقيمة 2 وتنتهي بقيمة اقل من القيمة الموجودة في المتغير n. فعندما تكون قيمة n هي 2 فان الحلقة الداخلية سوف تتكرر صفر من المرات كما في المثال التالي:

n=2 for x in range(2,n): print(x)

لاحظ ان الكود السابق لايطبع اي قيمة للمتغير x. لان عدد مرات التكرار هنا صفر.

لذلك سوف تعتبر حلقة التكرار الداخلية انتهت بشكل كامل وسوف ينفذ الكود البرمجي الذي يقع داخل العبارة else والذي يفيد بأن قيمة العدد 2 هي عدد اولي. ويعود الكود البرمجي الى الحلقة الخارجية ليضع القيمة 3 داخل المتغير n ويكوّن حلقة تكرار داخلية جديد من الدالة range تبتدأ بالقيمة 2 وتنتهي بقيمة أقل من 3. فيتكون لدينا حلقة تكرار واحدة كما في المثال التالي:

n=3 for x in range(2,n): print(x)
2

يقوم الكود البرمجي داخل الحلقة الداخلية بالتأكد ما اذا كانت القيمة 3 للمتغير n تقبل القسمة بدون باقي على قيمة x والتي هي هنا 2 فيجد أن شرط التحقق لا يتحقق فيخرج من الحلقة الداخلية بعد اكتمالها لينفد السطر البرمجي في العبارة else كما شرحنا سابقاً. تتكرر العملية بالذهاب الى الحلقة الخارجية وإعطاء n القيمة 4 ويتم تكوين حلقة تكرارية جديد من خلال الدالة range تبدأ من 2 وتنتهي بـقيمة أقل من 4 فيتكون لدينا حلقتي تكرار كما في المثال التالي:

n=4 for x in range(2,n): print(x)
2 3

يقوم الكود البرمجي داخل الحلقة الداخلية بالتأكد ما اذا كانت القيمة 4 للمتغير n تقبل القسمة بدون باقي على قيمة x والتي تبدأ اولا بـ 2 فيجد أن شرط التحقق يتحقق فيبدأ تنفيذ السطر البرمجي المحكوم بتحقق الشرط وهو طباعة حاصل ضرب القيمة x بقيمة حاصل قسمة n بالقيمة x ثم يتم استدعاء العبارة break للخروج من حلقة التكرار الداخلية لأنه لا يوجد داعي للتحقق من كون قيمة x الثانية هي قاسم للعدد 4 فيكفي وجود قيمة واحدة غير العدد نفسه لأثبات أن العدد غير أولي. سوف يعود الكود البرمجي بعدها الى الحلقة الخارجية دون تنفيذ السطر البرمجي للعبارة else لأن حلقة التكرار تم انهاؤها قبل أن تكتمل. تتكرر العملية بالذهاب الى الحلقة الخارجية على هذا المنوال حتى تنتهي عناصر الحلقة الخارجية. كلما زادت قيمة n كلما زاد عدد مرات التكرار التي يتخطاها الكود البرمجي بالعبارة break فيصبح تنفيذ الكود أسرع مقارنة بكود برمجي يقوم بنفس المهمة دون استخدام العبارة break. لإثبات هذه المعلومة لنقم بكتابة الكود البرمجي السابق بدون استخدام عبارة break بحيث يتطلب الخروج من الحلقة الداخلية إكمال جميع الحلقات التكرارية كما في المثال التالي:

%%timeit prime=[] non_prime=[] for n in range(2, 10000): divisor=0 for x in range(2, n): if n % x == 0: divisor+=1 if divisor: non_prime.append(n) else: prime.append(n) print("prime=",len(prime)) print("non-prime=",len(non_prime))
%%timeit prime=[] non_prime=[] for n in range(2, 10000): for x in range(2, n): if n % x == 0: non_prime.append(n) break else: prime.append(n) print("prime=",len(prime)) print("non-prime=",len(non_prime))

استخدام عبارة المواصلة continue

تسخدم العبارة continue داخل حلقات التكرار عندما يرغب المبرمج في عدم تنفيذ الاسطر البرمجية التي تلي العبارة continue بحيث يذهب البرنامج الى تنفيذ الحلقة التكرارية التالية كما هو موضح في المثال التالي:

fruits = ["apple", "banana", "cherry"] for x in fruits: if x == "banana": continue print(x)
apple cherry

فحلقة التكرار السابقة تحتوي على شرط عند تحققه فإن البرنامج يتخطى باقي الاسطر البرمجية التي تقع داخل الحلقة التكرارية والتي هي هنا امر الطباعة ويذهب الى تنفيذ الحلقة التكرارية التالية. فعند تحقق الشرط بأن تكون قيمة x تساوي banana فإن البرنامج تخطى امر طباعة banana ويذهب للحلقة التي بعدها تضع قيمة x بالقيمة cherry وعند عدم تحقق الشرط فان امر طباعة cherry يتحقق.

استخدام حلقة التكرار لإنشاء القوائم

هناك طريقتان شائعتان لإنشاء القوائم بواسطة حلقات التكرار:

الطريقة المطولة: تعتمد على إنشاء قائمة فارغة ومن ثم استخدام الامر append لاضافة العناصر لهذه القائمة كما في المثال التالي:

fruits = ["apple", "banana", "cherry", "kiwi", "mango"] newlist = [] for x in fruits: if "a" in x: newlist.append(x) newlist
['apple', 'banana', 'mango']

الطريقة المختصرة: تعتبر هذه الطريقة هي الاكثر شيوعاً والمفضلة لدى المبرمجين لأنها تسمح بإنشاء القائمة من خلال كتابة سطر برمجي واحد فقط. فلو أردنا ان نكتب المثال السابق بالطريقة المختصرة لأصبح الكود بالشكل التالي:

fruits = ["apple", "banana", "cherry", "kiwi", "mango"] newlist = [x for x in fruits if "a" in x] newlist
['apple', 'banana', 'mango']

حلقة تكرار while

الحلقة التكرارية while تستخدم عندما يكون عدد مرات التكرار التي يريد المبرمج القيام بها غير معروف مسبقاً. لذلك تستخدم هذه الحلقة التكرارية عندما نريد أن نقوم بعمليات تكرار غير منتهية أو عندما لا يتم معرفة إمكانية الخروج من الحلقة التكرارية إلا بعد اجراء بعض العمليات داخل الحلقة التكرارية. ويكون التركيب اللغوي لهذه الحلقة مشابها لحد ما لحلقة for كما في المثال التالي:
a=1 while a<10: print(a) a=a+2
من المثال السابق يتضح الآتي:
  1. تبدأ حلقة التكرار بكلمة while.
  2. استمرارية حلقة التكرار يكون محكوماً بالشرط الذي يتلو كلمة while.
  3. ينتهي السطر الاول من الحلقة بنقطتين فوق بعض ":".
  4. يترك مسافة بمقدار حرف واحد على الأقل (Indentation) قبل كتابة الأوامر التي يراد تكرارها. ومن المتعارف عليه في لغة بايثون أن يترك فراغ بمقدار 4 أحرف.
يمكن كتابة المعنى الحرفي للمثال السابق على النحو التالي: "طالما قيمة a أقل من 10 قم بتكرار طباعة القيمة a".
وبما أن قيمة a تتزايد داخل حلقة التكرار بمقدار 2 في كل مرة فإن طباعة القيمة الجديدة لـ a سوف تتكرر الى أن ينتفي شرط تحقق الحلقة. عندها يتم الخروج من حلقة التكرار while وتتوقف طباعة قيم a. تمعن في الشكل التالي لفهم ما يقوم به مفسر بايثون داخل حلقة while.

ماذا تتوقع ان يحدث لو قمنا بحذف السطر الرابع من الكود السابق بحيث تظل قيمة a بدون تغيير. ربما قد هداك تفكيرك اذا كان سليماً الى اننا سوف نحصل على حلقة تكرار غير منتهية تقوم بطباعة قيمة a الى ما لا نهاية عندها سوف يتوقف مفسر بايثون من اداء اي مهام اخرى وسوف تضطر الى الضغط على زر الايقاف الاجباري (زر المربع الاسود الموجود فس شريط الادوات) لايقاف عملية الطباعة او الضغط مرتين متتاليتين على حرف i من لوحة المفاتيح او اختيار interrupt من قائمة Kernel.

تمارين استكشافية

1. قم بكتابة الكود البرمجي السابق بعد حذف السطر الأخير ولاحظ كيف تتم طباعة القيمة a. حاول ايقاف علمية الطباعة باستخدام أحد الطرق السابقة.
2. حاول أن تتعرف على ما إذا كان الكودين البرمجيين التاليين سوف ينتج عنهما حلقة تكرار منتهية أو غير منتهية بدون تشغيل الكود. بعد أن تكون قد حددت إجابتك قم بتشغيل الكود لمعرفة الإجابة الصحيحة؟.
# الكود الاول n = 1 while n > 0: n /= 2
# الكود الثاني n = 2 while n > 0: if n % 2 == 0: n += 1 else: n -= 1

كما يمكن استخدام العبارة break مع حلقة التكرار while كما فعلنا من قبل مع حلقة التكرار for كما في المثال التالي:

i = 1 while i < 6: print(i) if i == 3: break i += 1
1 2 3

واستخدام عبارة else سوف يكون بنفس الطريقة التي تعلمناها مع حلقة التكرار كما في المثالين التاليين:

i = 1 while i < 6: print(i) if i == 3: break i += 1 else: print("I completed the loop successfully")
1 2 3
i = 1 while i < 6: print(i) if i == 13: break i += 1 else: print("I completed the loop successfully")
1 2 3 4 5 I completed the loop successfully

وكذلك استخدام العبارة continue يمكن استخدامها مع حلقة تكرار while بنفس الطريقة التي تعلمناها مع حلقة التكرار for كما في المثال التالي:

i = 0 while i < 6: i += 1 if i == 3: continue print(i)
1 2 4 5 6

استخدام دالة ادخال البيانات ()input مع حلقة التكرار while

يكثر استخدام حلقة التكرار while مع دالة الادخال ()input والتي تطلب من مستخدم البرنامج ادخال البيانات التي يحتاجها البرنامج لاتمام العمليات المطلوبة من البرنامج. فعلى سبيل المثال يمكن كتابة برنامج يطلب من المستخدم ادخال قيمة نصية بحيث يقوم البرنامج بطباعة عدد أحرف القيمة النصية التي ادخلها المستخدم. لتمكين المستخدم من ادخال قيم نصية مختلفة في كل مرة نستخدم حلقة التكرار while بحيث نطلب من المستخدم ادخال قيمة اخرى لحساب عدد حروفها وطباعتها على الشاشة. سوف تستمر هذا العملية الى ما لا نهاية لذلك يفضل ان يعمل شرط داخل حلقة التكرار while بحيث في حال تحققه يقوم بالخروج من الحلقة التكرارية كما هو موضح في البرنامج التالي:

while True: txt=input("please enter a text otherwise write q to quit: ") if txt=="q": break else: print("You entered ",len(txt)," letters")
please enter a text otherwise write q to quit: hello You entered 5 letters please enter a text otherwise write q to quit: my name is a ahmad You entered 18 letters please enter a text otherwise write q to quit: q

للاستزادة حول استخدام الدالة ()input يمكنك قراءة الفصل السابع من هذا الكتاب.